package dmdemo

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

type TerminalData struct {
	ID                  string    `gorm:"primaryKey;size:64"`
	TerminalTime        time.Time `gorm:"column:TERMINAL_TIME"`                       //日期从20240501~20240531  时间任意
	TerminalSn          string    `gorm:"column:TERMINAL_SN;size:20"`                 //SN00000001~SN00030000  内随机
	TerminalSim         string    `gorm:"column:TERMINAL_SIM;size:12"`                //SIM00000001~SIM00030000 内随机
	Longitude           float64   `gorm:"column:LONGITUDE;type:NUMERIC(12,6)"`        //在长沙湖南内的坐标
	Latitude            float64   `gorm:"column:LATITUDE;type:NUMERIC(12,6)"`         //在长沙湖南内的坐标
	ELEVATION           float64   `gorm:"column:ELEVATION;type:NUMERIC(22,6)"`        //随机
	DIRECTION           string    `gorm:"column:DIRECTION;size:3"`                    //随机 0~365
	TERMINAL_MILES      float64   `gorm:"column:TERMINAL_MILES;type:NUMERIC(8)"`      //随机
	TERMINAL_MILES_ADAY float64   `gorm:"column:TERMINAL_MILES_ADAY;type:NUMERIC(4)"` //随机
	SPEED               float64   `gorm:"column:SPEED;type:NUMERIC(3)"`               //随机

	IsFix                bool `gorm:"column:IS_FIX"`               //0~1随机
	TERMINAL_OFF_LINE    bool `gorm:"column:TERMINAL_OFF_LINE"`    //0~1随机
	TERMINAL_OVER_SPEED  bool `gorm:"column:TERMINAL_OVER_SPEED"`  //0~1随机
	TERMINAL_TIRED_DRIVE bool `gorm:"column:TERMINAL_TIRED_DRIVE"` //0~1随机
	TERMINAL_GNSS_ERROR  bool `gorm:"column:TERMINAL_GNSS_ERROR"`  //0~1随机
	TERMINAL_ANT_OPRN    bool `gorm:"column:TERMINAL_ANT_OPRN"`    //0~1随机
	TERMINAL_ANT_SHORT   bool `gorm:"column:TERMINAL_ANT_SHORT"`   //0~1随机
	TERMINAL_UNDER_VOL   bool `gorm:"column:TERMINAL_UNDER_VOL"`   //0~1随机
	TERMINAL_NO_VOL      bool `gorm:"column:TERMINAL_NO_VOL"`      //0~1随机
	TERMINAL_ACC_STATUS  bool `gorm:"column:TERMINAL_ACC_STATUS"`  //0~1随机
	TERMINAL_NET_RSSI    bool `gorm:"column:TERMINAL_NET_RSSI"`    //0~1随机
	TERMINAL_GNSS_CNT    bool `gorm:"column:TERMINAL_GNSS_CNT"`    //0~1随机
	FIX_BEIDOU           bool `gorm:"column:FIX_BEIDOU"`           //0~1随机
	FIX_GPS              bool `gorm:"column:FIX_GPS"`              //0~1随机
	FISX_GLONASS         bool `gorm:"column:FISX_GLONASS"`         //0~1随机
	FIX_GALIEO           bool `gorm:"column:FIX_GALIEO"`           //0~1随机

	VEHICLES_CODE string `gorm:"column:VEHICLES_CODE;size:60"`           // 湘A00001~湘A30000 内随机
	VEH_PLATE_NUM string `gorm:"column:VEH_PLATE_NUM;size:20"`           // 湘A00001~湘A30000内随机
	REGION_CODE   uint64 `gorm:"column:REGION_CODE;size:19;type:BIGINT"` // 0~1000 内随机
	OWN_UNIT_ID   uint64 `gorm:"column:OWN_UNIT_ID;size:19;type:BIGINT"` // 0~1000 内随机
	USE_UNIT_ID   uint64 `gorm:"column:USE_UNIT_ID;size:19;type:BIGINT"` // 0~1000 内随机
}

func (TerminalData) TableName() string {
	return "TERMINAL_DATA_202401_TEST"
}

var charset = "abcdefghijklmnopqrstuvwxyz" +
	"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
	"0123456789" +
	"!@#$%^&*()"

func randomString(length int) string {
	randomStr := make([]byte, length)
	for i := range randomStr {
		randomStr[i] = charset[rand.Intn(len(charset))]
	}
	return string(randomStr)
}

func randomDigString(prefix string, min, max int) string {
	return fmt.Sprintf("%s%08d", prefix, rand.Intn(max-min+1)+min)
}

func randomFloat(min, max float64) float64 {
	return min + rand.Float64()*(max-min)
}

func randomInt(min, max int) int {
	return rand.Intn(max-min+1) + min
}

func randomDate(min, max time.Time) time.Time {
	delta := max.Unix() - min.Unix()
	sec := rand.Int63n(delta) + min.Unix()
	return time.Unix(sec, 0)
}

func GenerateRandomTerminalData() TerminalData {
	// 定义日期范围
	minDate := time.Date(2024, 5, 1, 0, 0, 0, 0, time.UTC)
	maxDate := time.Date(2024, 5, 31, 23, 59, 59, 0, time.UTC)
	return TerminalData{
		ID:                   randomString(64),
		TerminalTime:         randomDate(minDate, maxDate),
		TerminalSn:           randomDigString("SN", 1, 30000),
		TerminalSim:          randomDigString("SIM", 1, 30000),
		IsFix:                false,                     // uint(randomInt(0, 1)),
		Longitude:            randomFloat(112.8, 113.1), // 长沙的经度范围
		Latitude:             randomFloat(28.1, 28.4),   // 长沙的纬度范围
		ELEVATION:            randomFloat(0, 500),
		DIRECTION:            fmt.Sprintf("%d", randomInt(0, 360)),
		TERMINAL_MILES:       randomFloat(0, 1000),
		TERMINAL_MILES_ADAY:  randomFloat(0, 500),
		SPEED:                randomFloat(0, 120),
		TERMINAL_OFF_LINE:    false, // uint(randomInt(0, 1)),
		TERMINAL_OVER_SPEED:  false, // uint(randomInt(0, 1)),
		TERMINAL_TIRED_DRIVE: false, // uint(randomInt(0, 1)),
		TERMINAL_GNSS_ERROR:  false, // uint(randomInt(0, 1)),
		TERMINAL_ANT_OPRN:    false, // uint(randomInt(0, 1)),
		TERMINAL_ANT_SHORT:   false, // uint(randomInt(0, 1)),
		TERMINAL_UNDER_VOL:   false, // uint(randomInt(0, 1)),
		TERMINAL_NO_VOL:      false, // uint(randomInt(0, 1)),
		TERMINAL_ACC_STATUS:  false, // uint(randomInt(0, 1)),
		TERMINAL_NET_RSSI:    false, // uint(randomInt(0, 1)),
		TERMINAL_GNSS_CNT:    false, // uint(randomInt(0, 1)),
		FIX_BEIDOU:           false, // uint(randomInt(0, 1)),
		FIX_GPS:              false, // uint(randomInt(0, 1)),
		FISX_GLONASS:         false, // uint(randomInt(0, 1)),
		FIX_GALIEO:           false, // uint(randomInt(0, 1)),
		REGION_CODE:          0,     // uint(randomInt(0, 1000)),
		VEHICLES_CODE:        randomDigString("湘A", 1, 30000),
		VEH_PLATE_NUM:        randomDigString("湘A", 1, 30000),
		OWN_UNIT_ID:          uint64(randomInt(0, 1000)),
		USE_UNIT_ID:          uint64(randomInt(0, 1000)),
	}
}

// 多线程生成 TerminalData 数组的函数
func GenerateTerminalDataArray(threadCount, arraySize int) []TerminalData {
	var wg sync.WaitGroup
	dataChannel := make(chan TerminalData, arraySize)

	// 每个线程生成指定数量的 TerminalData
	worker := func(count int) {
		defer wg.Done()
		for i := 0; i < count; i++ {
			dataChannel <- GenerateRandomTerminalData()
		}
	}

	// 计算每个线程需要生成的数量
	dataPerThread := arraySize / threadCount
	extraData := arraySize % threadCount

	// 启动线程
	for i := 0; i < threadCount; i++ {
		wg.Add(1)
		if i == 0 {
			go worker(dataPerThread + extraData)
		} else {
			go worker(dataPerThread)
		}
	}

	// 等待所有线程完成
	wg.Wait()
	close(dataChannel)

	// 收集所有生成的 TerminalData
	var result []TerminalData
	for data := range dataChannel {
		result = append(result, data)
	}

	return result
}
